package com.gmp.product.controller;

import java.math.BigDecimal;
import java.util.*;
import javax.servlet.http.HttpServletResponse;

import com.gmp.common.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.gmp.common.annotation.Log;
import com.gmp.common.core.controller.BaseController;
import com.gmp.common.core.domain.AjaxResult;
import com.gmp.common.enums.BusinessType;
import com.gmp.product.domain.SampleRetentionInfo;
import com.gmp.product.service.ISampleRetentionInfoService;
import com.gmp.common.utils.poi.ExcelUtil;
import com.gmp.common.core.page.TableDataInfo;

/**
 * 取样留样信息Controller
 *
 * @author Koi
 * @date 2025-10-27
 */
@RestController
@Api(tags = "取样留样信息管理")
@RequestMapping("/product/SampleRetention")
public class SampleRetentionInfoController extends BaseController {

    @Autowired
    private ISampleRetentionInfoService sampleRetentionInfoService;

    /**
     * 查询取样留样信息列表
     */
    @PreAuthorize("@ss.hasPermi('product:SampleRetention:list')")
    @GetMapping("/list")
    public TableDataInfo list(SampleRetentionInfo sampleRetentionInfo) {
        startPage();
        List<SampleRetentionInfo> list = sampleRetentionInfoService.selectSampleRetentionInfoList(sampleRetentionInfo);
        return getDataTable(list);
    }

    /**
     * 导出取样留样信息列表
     */
    @PreAuthorize("@ss.hasPermi('product:SampleRetention:export')")
    @Log(title = "取样留样信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, SampleRetentionInfo sampleRetentionInfo) {
        List<SampleRetentionInfo> list = sampleRetentionInfoService.selectSampleRetentionInfoList(sampleRetentionInfo);
        ExcelUtil<SampleRetentionInfo> util = new ExcelUtil<SampleRetentionInfo>(SampleRetentionInfo.class);
        util.exportExcel(response, list, "取样留样信息数据");
    }

    /**
     * 获取取样留样信息详细信息
     */
    @PreAuthorize("@ss.hasPermi('product:SampleRetention:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id) {
        return success(sampleRetentionInfoService.selectSampleRetentionInfoById(id));
    }

    /**
     * 新增取样留样信息
     */
    @PreAuthorize("@ss.hasPermi('product:SampleRetention:add')")
    @Log(title = "取样留样信息", businessType = BusinessType.INSERT)
    @ApiOperation(value = "新增取样留样信息")
    @PostMapping
    public AjaxResult add(@RequestBody SampleRetentionInfo sampleRetentionInfo) {
        // 生成主键ID（如果未传入）
        if (StringUtils.isBlank(sampleRetentionInfo.getId())) {
            sampleRetentionInfo.setId(UUID.randomUUID().toString().replaceAll("-", ""));
        }

        // 生成取样唯一标识sampleId（如果未传入）
        if (StringUtils.isBlank(sampleRetentionInfo.getSampleId())) {
            // 规则：S + 时间戳后8位 + 3位随机数（总长度12位，例如：S78901234567）
            String timeSuffix = String.valueOf(System.currentTimeMillis()).substring(4); // 取时间戳后8位
            String randomNum = String.format("%03d", new Random().nextInt(1000)); // 3位随机数（补0保证3位）
            sampleRetentionInfo.setSampleId("S" + timeSuffix + randomNum);
        }
         //TODO 设置成null
        // 判断是否需要留样，处理retentionId及留样剩余量计算
        if (sampleRetentionInfo.getIsRetention() != null ) {
            // 生成留样唯一标识retentionId（未传入时）
            if (StringUtils.isBlank(sampleRetentionInfo.getRetentionId())) {
                // 规则：R + 时间戳后8位 + 3位随机数（总长度12位，例如：R78901234567）
                String timeSuffix = String.valueOf(System.currentTimeMillis()).substring(4);
                String randomNum = String.format("%03d", new Random().nextInt(1000));
                sampleRetentionInfo.setRetentionId("R" + timeSuffix + randomNum);
            }
            if(sampleRetentionInfo.getIsRetention() == 0){
                sampleRetentionInfo.setStabilityRetentionQuantity(null);
                sampleRetentionInfo.setStabilityRetentionUsed(null);
                sampleRetentionInfo.setStabilityRetentionRemaining(null);
                sampleRetentionInfo.setStabilityRetentionEndDate(null);
                // 计算普通留样剩余量：留样量 - 留样领用量（处理空值/非数字场景）
                sampleRetentionInfo.setRetentionRemainingQuantity(calculateRemaining(
                        sampleRetentionInfo.getRetentionQuantity(),
                        sampleRetentionInfo.getRetentionUsedQuantity()
                ));
            }
            else{
                sampleRetentionInfo.setRetentionQuantity(null);
                sampleRetentionInfo.setRetentionUsedQuantity(null);
                sampleRetentionInfo.setRetentionRemainingQuantity(null);
                sampleRetentionInfo.setRetentionEndDate(null);
                // 计算稳定性留样剩余量：稳定性留样量 - 稳定性留样领用量（处理空值/非数字场景）
                sampleRetentionInfo.setStabilityRetentionRemaining(calculateRemaining(
                        sampleRetentionInfo.getStabilityRetentionQuantity(),
                        sampleRetentionInfo.getStabilityRetentionUsed()
                ));
            }

        } else {
            // 不需要留样时，清空所有留样相关字段
            sampleRetentionInfo.setRetentionId(null);
            sampleRetentionInfo.setRetentionQuantity(null);
            sampleRetentionInfo.setRetentionUsedQuantity(null);
            sampleRetentionInfo.setRetentionRemainingQuantity(null);
            sampleRetentionInfo.setStabilityRetentionQuantity(null);
            sampleRetentionInfo.setStabilityRetentionUsed(null);
            sampleRetentionInfo.setStabilityRetentionRemaining(null);
            sampleRetentionInfo.setRetentionEndDate(null);
            sampleRetentionInfo.setStabilityRetentionEndDate(null);
            sampleRetentionInfo.setCreatedTime(null);
        }

        // 根据orderId生成batchNumber（若batchNumber为空且orderId不为空）
        // 优化批号生成逻辑：缩短前缀+截取orderId后6位+短时间戳，减少长度
        if (StringUtils.isBlank(sampleRetentionInfo.getBatchNumber())
                && StringUtils.isNotBlank(sampleRetentionInfo.getOrderId())) {
            // 1. 前缀简化为"B_"（原"BATCH_"太长）
            // 2. orderId取后6位（避免orderId本身过长）
            String shortOrderId = sampleRetentionInfo.getOrderId().length() > 6
                    ? sampleRetentionInfo.getOrderId().substring(sampleRetentionInfo.getOrderId().length() - 6)
                    : sampleRetentionInfo.getOrderId();
            // 3. 时间戳取后4位（原7位太长，4位足够区分短时间内的生成）
            String timestampSuffix = String.valueOf(System.currentTimeMillis()).substring(8);
            // 最终格式：B_后6位订单号_4位时间戳（例如：B_123456_7890）
            sampleRetentionInfo.setBatchNumber("B_" + shortOrderId + "_" + timestampSuffix);
        }

        sampleRetentionInfo.setSampleDate(new Date());
        sampleRetentionInfo.setIsDelete(0);
        sampleRetentionInfo.setCreatedTime(new Date());

        return toAjax(sampleRetentionInfoService.insertSampleRetentionInfo(sampleRetentionInfo));
    }

    /**
     * 通用剩余量计算工具方法：处理空值、非数字，返回字符串结果
     *
     * @param total 总量（留样量/稳定性留样量）
     * @param used  已用量（留样领用量/稳定性留样领用量）
     * @return 剩余量字符串（无法计算时返回空）
     */
    private String calculateRemaining(String total, String used) {
        // 总量为空时，剩余量为空
        if (StringUtils.isBlank(total)) {
            return null;
        }
        // 已用量为空时，剩余量=总量
        if (StringUtils.isBlank(used)) {
            return total;
        }

        try {
            // 尝试转换为BigDecimal计算（支持小数，避免精度丢失）
            BigDecimal totalNum = new BigDecimal(total.trim());
            BigDecimal usedNum = new BigDecimal(used.trim());
            // 剩余量不能为负数，最小返回0
            BigDecimal remaining = totalNum.subtract(usedNum).max(BigDecimal.ZERO);
            return remaining.toString();
        } catch (NumberFormatException e) {
            // 非数字格式时，返回空（可根据业务调整为抛出异常）
            return null;
        }
    }


    /**
     * 修改取样留样信息
     */
    @PreAuthorize("@ss.hasPermi('product:SampleRetention:edit')")
    @Log(title = "取样留样信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SampleRetentionInfo sampleRetentionInfo) {
        return toAjax(sampleRetentionInfoService.updateSampleRetentionInfo(sampleRetentionInfo));
    }

    /**
     * 删除取样留样信息
     */
    @PreAuthorize("@ss.hasPermi('product:SampleRetention:remove')")
    @Log(title = "取样留样信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable String[] ids) {
        return toAjax(sampleRetentionInfoService.removeBatchByIds(Arrays.asList(ids)));
    }
}
